package com.un.ebs.inventory.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.un.ebs.core.exception.BusinessException;
import com.un.ebs.core.util.DateUtils;
import com.un.ebs.core.util.StringUtils;
import com.un.ebs.inventory.domain.InventoryNoteType;
import com.un.ebs.inventory.domain.InventoryNoteTypeExt;
import com.un.ebs.inventory.dto.InventoryNoteTypeAddDto;
import com.un.ebs.inventory.dto.InventoryNoteTypeUpdateDto;
import com.un.ebs.inventory.enums.InventoryTypeEnum;
import com.un.ebs.inventory.enums.OrderNoteTypeEnum;
import com.un.ebs.inventory.mapper.InventoryNoteTypeExtMapper;
import com.un.ebs.inventory.mapper.InventoryNoteTypeMapper;
import com.un.ebs.inventory.service.InventoryNoteTypeService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author liubo
 * @since 2020-05-23
 */
@Service
public class InventoryNoteTypeServiceImpl extends ServiceImpl<InventoryNoteTypeMapper, InventoryNoteType> implements InventoryNoteTypeService {

    @Resource
    private InventoryNoteTypeExtMapper inventoryNoteTypeExtMapper;

    @Override
    public void add(InventoryNoteTypeAddDto req) {
        add(req, null);
    }

    public void add(InventoryNoteTypeAddDto req, String noteTag) {
        if (!StringUtils.isNullOrEmpty(req.getCode())) {
            InventoryNoteTypeExt ext = queryOneByCode(req.getCode());
            if (ext != null) {
                throw new BusinessException("code 不能重复。");
            }
        }

        InventoryNoteType obj = new InventoryNoteType();
        obj.setName(req.getName());
        obj.setInventoryType(req.getInventoryType());
        obj.setProfix(req.getProfix());
        obj.setOrderLen(req.getOrderLen());
        obj.setIsDelete(false);
        obj.setNoteTag(noteTag);
        obj.setRemark(req.getRemark());
        obj.setPrintTemplate(req.getPrintTemplate());
        obj.setCode(req.getCode());
        obj.setWorkflowId(req.getWorkflowId());
        obj.insert();
    }

    @Override
    public void update(InventoryNoteTypeUpdateDto req) {
        LambdaQueryWrapper<InventoryNoteType> lq = Wrappers.lambdaQuery();
        lq.ne(InventoryNoteType::getId, req.getId());
        lq.eq(InventoryNoteType::getCode, req.getCode());
        if (baseMapper.selectCount(lq) > 0) {
            throw new BusinessException("code 不能重复。");
        }

        InventoryNoteType obj = getById(req.getId());
        obj.setName(req.getName());
        obj.setInventoryType(req.getInventoryType());
        obj.setProfix(req.getProfix());
        obj.setOrderLen(req.getOrderLen());
        obj.setRemark(req.getRemark());
        obj.setPrintTemplate(req.getPrintTemplate());
        obj.setCode(req.getCode());
        obj.setWorkflowId(req.getWorkflowId());
        obj.updateById();
    }

    @Override
    public InventoryNoteTypeExt queryById(String id) {
        return inventoryNoteTypeExtMapper.selectById(id);
    }

    @Override
    public InventoryNoteTypeExt queryOneByType(InventoryTypeEnum type) {
        List<InventoryNoteTypeExt> list = queryByType(type);
        if (StringUtils.isNullOrEmpty(list)) {
            throw new BusinessException("业务类别 【" + type.getDesc() + "】 没有定义。");
        }
        if (list.size() != 1) {
            throw new BusinessException(String.format("%s 类型的业务定义找到 %n 笔，此处只能为 1笔。", type.getDesc(), list.size()));
        }

        return list.get(0);
    }

    @Override
    public InventoryNoteTypeExt queryOneByCode(String code) {
        if (StringUtils.isNullOrEmpty(code)) {
            throw new BusinessException("code 不能为空。");
        }
        LambdaQueryWrapper<InventoryNoteTypeExt> lq = Wrappers.lambdaQuery();
        lq.eq(InventoryNoteTypeExt::getCode, code);
        lq.eq(InventoryNoteTypeExt::getIsDelete, false);
        return inventoryNoteTypeExtMapper.selectOne(lq);
    }

    @Override
    public List<InventoryNoteTypeExt> querInType() {
        //return queryAll().stream().filter(s -> s.getInventoryType() == InventoryTypeEnum.IN || s.getInventoryType() == InventoryTypeEnum.ACCOUNT_INIT).collect(Collectors.toList());
        return queryAll().stream().filter(s -> s.getInventoryType() == InventoryTypeEnum.IN).collect(Collectors.toList());
    }

    @Override
    public List<InventoryNoteTypeExt> queryOutType() {
        return queryAll().stream().filter(s -> s.getInventoryType() == InventoryTypeEnum.OUT).collect(Collectors.toList());
    }

    @Override
    public List<InventoryNoteTypeExt> queryMoveType() {
        return queryAll().stream().filter(s -> s.getInventoryType() == InventoryTypeEnum.MOVE).collect(Collectors.toList());
    }

    @Override
    public List<InventoryNoteTypeExt> queryByType(InventoryTypeEnum type) {
        if (type == null) {
            return queryAll();
        } else {
            return queryAll().stream().filter(s -> s.getInventoryType() == type).collect(Collectors.toList());
        }
    }

    @Override
    public List<InventoryNoteTypeExt> queryByType(OrderNoteTypeEnum orderType, InventoryTypeEnum type, boolean autoCreate) {
        List<InventoryNoteTypeExt> list = queryByType(type);
        if (StringUtils.isNullOrEmpty(list) && autoCreate) {
            InventoryNoteTypeAddDto obj = new InventoryNoteTypeAddDto();
            obj.setName(orderType.getDesc());
            obj.setInventoryType(type);
            obj.setOrderLen(4);
            obj.setProfix(String.format("%02d", type.getCode()));
            add(obj, orderType.toString());
        }
        return queryByType(type);
    }

    //@Cacheable(cacheNames = "inventory_note_type")
    @Override
    public List<InventoryNoteTypeExt> queryAll() {
        LambdaQueryWrapper<InventoryNoteTypeExt> lq = Wrappers.lambdaQuery();
        lq.eq(InventoryNoteTypeExt::getIsDelete, false);
        return inventoryNoteTypeExtMapper.selectList(lq);
    }

    //@CacheEvict(cacheNames = "inventory_note_type", allEntries = true)
    @Override
    public void delete(String id) {
        getBaseMapper().deleteById(id);
    }

    @Override
    public String queryCode(String typeId, int currentMaxCode) {
        InventoryNoteTypeExt type = queryById(typeId);
        return String.format("%s-%s%04d", type.getProfix(), DateUtils.formatDate(new Date(), "yyyyMMdd"), currentMaxCode + 1);
    }

    @Override
    public String queryCode(String profix, String dateFormat, int seqLen, int currentMaxCode) {
        return String.format("%s-%s0%dd", profix, dateFormat, seqLen, currentMaxCode + 1);
    }

}